// 将联合类型转成交叉类型
// 需要使用: 联合类型的分布式特性、函数参数的逆变特性、infer推断
type A = { id: 1; name: "jack" } extends { id: 1 } ? 1 : 2; // 1
// 函数参数的逆变特性，
/**
 * 参数少的按理来说是可以赋值给参数多的，但是这里是逆变的，因此参数多的可以赋值给参数少的。
 */
type AA = ((e: { id: 1; name: "jack" }) => void) extends (e: { id: 1 }) => void
  ? 1
  : 2; // 2 函数参数的逆变特性。
// 利用分发特性
type UnionToInterSection<U> =
  // 利用分发特性，将联合类型构建成联合类型的函数。
  (U extends any ? (arg: U) => any : never) extends (arg: infer P) => any
    ? P
    : never; // 第二个extends 左侧是：(args:{id:1})=>any | (args: {name:'jack'})=>any;
//函数的是逆变的，因此第二个extends 的右侧应该是小于左侧的，因此应该是：(args:{id:1} & {name:'jack'})=>any
type as = UnionToInterSection<{ id: 1 } | { name: "jack" }>;

// 将元祖类型转成交叉类型
type C = Tuple2InterSection<[{ id: 1 }, { name: "jack" }, { sex: "nan" }]>; //{id:1} & {name:'jack'} & {sex:'nan'}
type Tuple2InterSection<T> = T extends [infer F, ...infer R]
  ? F & Tuple2InterSection<R>
  : unknown; //unknown也会被忽略 这里使用never得到的结果也只能是never
export {};

type Tuple2InterSection2<T extends any[]> = T extends [infer F, ...infer R]
  ? F & Tuple2InterSection2<R>
  : unknown;
type NewC = Tuple2InterSection<C>;
type asd = { id: 1 } & { name: "jack" } & unknown;

/**
 * 联合类型转成交叉类型
 */
type Union2Intersection<T> = (
  T extends any ? (args: T) => any : never
) extends (args: infer P) => any
  ? P
  : never;

type AAA = Union2Intersection<{ id: number } | { name: "rose" }>;
